
<script setup lang="ts">
import { ref, computed, watch,onActivated } from 'vue'
import hljs from 'highlight.js/lib/core'

export interface Props {
  code: string
  language?: string
  autodetect?:boolean
  ignoreIllegals?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  language :'',
  autodetect: true,
  ignoreIllegals:true
  
})



function escapeHtml(value: string): string {
    return value
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#x27;')
}

const language = ref(props.language)
watch(() => props.language, (newLanguage) => {
    language.value = newLanguage
})

const preview = ref("")
const hidden  = ref(true)

function toggleHidden(){
  hidden.value = !hidden.value
}

// watch并不能得到初始数据
const length = computed(():number => {
    let lines = props.code.split('\n')
    if(lines && lines.length > 10){
        let new_lines = []
        for(var i=0;i<10;i++){
            new_lines.push(lines[i])
        }
        preview.value = new_lines.join('\n')
    }
    return lines.length;
})

const autodetect = computed(() => props.autodetect || !language.value)

const cannotDetectLanguage = computed(() => !autodetect.value && !hljs.getLanguage(language.value))

const className = computed((): string => {
    if (cannotDetectLanguage.value) {
        return ''
    } else {
        return `hljs ${language.value}`
    }
})
const highlightedPreview = computed((): string => {
    // No idea what language to use, return raw code
    if(preview.value==""){
        return "";
    }
    if (cannotDetectLanguage.value) {
        console.warn(`The language "${language.value}" you specified could not be found.`)
        return escapeHtml(props.code)
    }

    if (autodetect.value) {
        const result = hljs.highlightAuto(preview.value)
        language.value = result.language ?? ''
        return result.value
    } else {
        const result = hljs.highlight(preview.value, {
            language: language.value,
            ignoreIllegals: props.ignoreIllegals,
        })
        return result.value
    }
})

const highlightedCode = computed((): string => {
    // No idea what language to use, return raw code
    if (cannotDetectLanguage.value) {
        console.warn(`The language "${language.value}" you specified could not be found.`)
        return escapeHtml(props.code)
    }

    if (autodetect.value) {
        const result = hljs.highlightAuto(props.code)
        language.value = result.language ?? ''
        return result.value
    } else {
        const result = hljs.highlight(props.code, {
            language: language.value,
            ignoreIllegals: props.ignoreIllegals,
        })
        return result.value
    }
})
</script>

<template>

<pre class="code-block">
  <code :class="className" v-if="length > 10 && hidden" v-html="highlightedPreview"></code>
  <code :class="className" v-else v-html="highlightedCode"></code>
  <div class="hidden-button" v-if="length > 10" @click="toggleHidden">  {{hidden?'show More':'hidden'}}</div>
 </pre>
</template>

<style scoped>
.code-block{
    display: flex;
    position: relative;
}
pre.code-block code.hljs{
    width:100%;
    text-align: left;
} 

.code-block .hidden-button{
position: absolute;
    bottom: -10px;
    width: 100%;
    background: burlywood;
    color: black;
}
</style>

